#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <fstream>
#include <algorithm>
#include <stdio.h>



// link with -lboost_filesystem-gcc -lboost_program_options-gcc
// program_options_helper.cpp
//-lboost_filesystem-gcc-d
//-L/usr/local/lib





// my functions
#include <print_error.h>
#include <stlhelper.h>
#define DEBUG_LEVEL 6
#include <debug_func.h>
#include <boost/filesystem/path.hpp>
#include <boost/regex.hpp>
#include "get_arg.h"

using std::string;
using std::cerr;
using std::string;
using std::vector;
using std::ofstream;
using std::ifstream;
using std::cerr;
using std::cout;
using std::max;
using boost::filesystem::path;
#define DEFAULT_CODEML_PATH "/net/cpp-group/tools/paml/"
using namespace program_options_helper;
namespace po = boost::program_options_lg;


//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool is_regular_expression_valid(const string& regex, string& error_msg)
{
	try
	{
		boost::regex try_regex(regex);
	}
	catch(std::exception& e)
	{
		error_msg = e.what();
		return false;
	}
	return true;

}

bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{

	//
	// checked mandatory arguments
	//
	po::options_description mandatory_args("Mandatory Arguments");
	mandatory_args.add_options()
	("regex,r", 				po::value<string>(&args.regex)
										->set_name("REGEX"),
									"Regular expression.");





	args.optional_args.add_options()
	("input_file,i", 			po::value<string>(&args.file_input)
										->set_name("FILE")
										->default_value("STDIN"),
									"Sequence pairs results to be filtered.")
	("ids_only,I",				po::bool_switch(&args.ids_only), 	
									"Only print out the identifiers.")
	("alt_regex,a", 			po::value<string>(&args.alt_regex)
									 ->set_name("REGEX"),
									"Regular expression matching the other identifier.\n"
									"One identifier must match --regexc and the other "
									"--alt_regex."
									"If not specified, both identifiers must match --regex.")
	("#comment,#",				po::value<string>(&args.comment_letters)
										->set_name("LETTERS")
										->default_value("#"),
									"Use one of these letters to begin a "
									"commented line.");


	//	Parse all arguments
	//
	args.add_std_options();
	po::options_description all_args("");
	all_args

				//	Mandatory arguments
				.add(mandatory_args)

				//	Optional arguments
				.add(args.optional_args);



	// parse command line
	po::variables_map vm;
	po::store(po::command_line_parser(argc, argv)
								.options(all_args)

								.run(), vm);
	po::notify(vm);

	if (vm.count("version"))
	{
		print_version(	cerr, *argv, "1.4\n"
						"\tHistory: \n\n"
						"\tv 1.0"
						"13-01-2005\1"
						"First Version\1"
						"Hopefully faster than perl.\n"
						"\tv 1.1"
						"23-08-2005\1"
						"Single input file.\n"
						"\tv 1.2"
						"15-11-2005\1"
						"Second pattern.\n"
						"\tv 1.3\1"
						"04-01-2006\1"
						"For Andreas: Hash start comment lines. Fix bugs in handling input. "
						"Upgrade to common code for sequence pair identifiers\n"
						"\tv 1.4\1"
						"27-03-2006\1"
						"Comments can begin with user-defined letters. Defaults to hash '#'\n"
						"\tv 1.5\1"
						"14-04-2007\1"
						"Forget about patterns. Just use regular expressions.\n"

					  
			);
		return false;
	}
	if (vm.count("help"))
	{
		string exe_description =
					"Takes sequence pair results and only keeps those matching regular "
					"expressions.\n";

		//
		//	Only output visible arguments for help string
		//
		po::options_description visible_args("");
		visible_args

					//	Mandatory arguments
					.add(mandatory_args)

					//	Optional arguments
					.add(args.optional_args);

		print_usage(cerr, string(*argv),	"--regex REGEX\n"
											"--input_file FILE\n"
											"[--alt_regex REGEX]\n"
											"[OPTIONS]\n"
											" > RESULT.FILE",
							visible_args, exe_description, 80);
		return false;
	}
	check_required_options(vm, mandatory_args);
	if (!vm.count("alt_regex"))
		args.alt_regex = args.regex;

	string error_msg;
	if (!is_regular_expression_valid(args.regex, error_msg))
		throw std::runtime_error("Invalid regular expression specified in --regex:\n" +
										error_msg);
	if (!is_regular_expression_valid(args.alt_regex, error_msg))
		throw std::runtime_error("Invalid regular expression specified in --alt_regex:\n" +
										error_msg);
	args.open_err_log();
	return true;
}













